home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 2000
/
MacHack 2000.toast
/
pc
/
The Hacks
/
X-MENu
/
X-MENu.cp
< prev
Wrap
Text File
|
2000-06-23
|
6KB
|
309 lines
/*
X-MENu
written by Jim Correia
MacHack 15
June, 2000
correia@barebones.com
*/
#include <Appearance.h>
#ifdef powerc
#pragma options align=mac68k
#endif
typedef struct
{
short last_offset;
short last_right;
short reserved;
struct
{
MenuHandle menu;
short menu_left;
} menus[1];
} **menu_list;
#ifdef powerc
#pragma options align=reset
#endif
static UniversalProcPtr orig_draw_menubar;
static MBarHookUPP orig_mbar_hook = nil;
static Handle icon_suite;
static UniversalProcPtr orig_menu_select = nil;
static UniversalProcPtr mbar_hook = nil;
static UniversalProcPtr old_hook = nil;
ProcInfoType __procinfo = kPascalStackBased;
static MenuHandle get_apple_menu(void)
{
MenuHandle apple_menu = nil;
menu_list list = (menu_list)LMGetMenuList();
if ((**list).last_offset != 0)
apple_menu = (**list).menus[0].menu;
return apple_menu;
}
static MenuHandle get_file_menu(void)
{
MenuHandle file_menu = nil;
menu_list list = (menu_list)LMGetMenuList();
if ((**list).last_offset >= 1)
file_menu = (**list).menus[1].menu;
return file_menu;
}
static UniversalProcPtr ApplyTrapPatch(short trap, UniversalProcPtr patchPtr)
{
UniversalProcPtr trapPtr;
if (patchPtr == nil)
return nil;
trapPtr = NGetTrapAddress (trap, (trap & 0x0800) ? ToolTrap : OSTrap);
NSetTrapAddress (patchPtr, trap, (trap & 0x0800) ? ToolTrap : OSTrap);
return trapPtr;
}
enum
{
DrawMenuBarUPPInfo = kPascalStackBased,
MenuSelectUPPInfo = kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Point)))
};
static void init_icon()
{
OSErr anErr = noErr;
if ( ! icon_suite )
anErr = GetIconSuite(&icon_suite, -16386, svAllAvailableData);
}
static void PatchedDrawMenubar()
{
OSErr anErr = noErr;
GrafPtr save_port;
CGrafPtr wmgr_port;
if ( orig_draw_menubar )
CALL_ZERO_PARAMETER_UPP( orig_draw_menubar, DrawMenuBarUPPInfo );
GetPort(&save_port);
GetCWMgrPort(&wmgr_port);
SetPort((GrafPtr)wmgr_port);
init_icon();
if ( icon_suite != nil )
{
short height = LMGetMBarHeight();
short width = 640;
Rect r, erase_rect;
GDHandle device = GetMainDevice();
if ( height < 20 )
height = 20;
width = ( (**device).gdRect.right - (**device).gdRect.left );
r.left = width / 2 - 8;
r.right = r.left + 16;
r.top = 2;
r.bottom = r.top + 16;
erase_rect = r;
InsetRect(&erase_rect, -4, 0);
erase_rect.top = 0;
erase_rect.bottom = height;
DrawThemeMenuTitle(&erase_rect, &erase_rect, kThemeMenuActive, 0L, nil, nil);
anErr = PlotIconSuite(&r, atNone, ttNone, icon_suite);
// now nuke the original apple menu
erase_rect.left = 10;
erase_rect.right = 30;
DrawThemeMenuTitle(&erase_rect, &erase_rect, kThemeMenuActive, 0L, nil, nil);
}
else
Debugger();
SetPort(save_port);
}
static SInt16 MyMBARHook(Rect *r)
{
SInt16 result = 0;
short width = 640;
Rect icon_rect;
GDHandle device = GetMainDevice();
width = ( (**device).gdRect.right - (**device).gdRect.left );
icon_rect.left = width / 2 - 8;
icon_rect.right = icon_rect.left + 16;
icon_rect.top = r->top;
icon_rect.bottom = icon_rect.top + 16;
if ( SectRect(&icon_rect, r, &icon_rect) )
{
result = 1;
}
else if ( r->left <= 30 ) // we are the apple menu
{
result = 1;
}
return result;
}
static long MenuSelectPatch(Point pt)
{
GrafPtr save_port;
CGrafPtr wmgr_port;
long result = -1;
short height = LMGetMBarHeight();
short width = 640;
Rect icon_rect;
GDHandle device = GetMainDevice();
MenuHandle apple_menu = get_apple_menu();
MenuHandle file_menu = get_file_menu();
if ( height < 20 )
height = 20;
width = ( (**device).gdRect.right - (**device).gdRect.left );
icon_rect.left = width / 2 - 8;
icon_rect.right = icon_rect.left + 16;
icon_rect.top = 0;
icon_rect.bottom = height;
if ( PtInRect(pt, &icon_rect) )
{
short width = 640;
Rect r, erase_rect;
GDHandle device = GetMainDevice();
OSErr anErr = noErr;
width = ( (**device).gdRect.right - (**device).gdRect.left );
r.left = width / 2 - 8;
r.right = r.left + 16;
r.top = 2;
r.bottom = r.top + 16;
erase_rect = r;
InsetRect(&erase_rect, -4, 0);
erase_rect.top = 0;
erase_rect.bottom = height;
GetPort(&save_port);
GetCWMgrPort(&wmgr_port);
SetPort((GrafPtr)wmgr_port);
DrawThemeMenuTitle(&erase_rect, &erase_rect, kThemeMenuSelected, 0L, nil, nil);
init_icon();
if ( icon_suite )
anErr = PlotIconSuite(&r, atNone, ttNone, icon_suite);
else
Debugger();
SetPort(save_port);
if ( apple_menu && file_menu )
{
short left = icon_rect.left + 8;
DeleteMenu((**apple_menu).menuID);
InsertMenu(apple_menu, -1);
CalcMenuSize(apple_menu);
left -= ( (**apple_menu).menuWidth / 2 );
result = PopUpMenuSelect(apple_menu, height, left, 0);
DeleteMenu((**apple_menu).menuID);
InsertMenu(apple_menu, (**file_menu).menuID);
}
}
else if ( pt.h <= 40 ) // we are the apple menu
{
result = 0;
}
if ( orig_menu_select && ( result == -1 ) )
{
UniversalProcPtr old_hook = LMGetMBarHook();
UniversalProcPtr mbar_hook = NewMBarHookProc(MyMBARHook);
LMSetMBarHook(mbar_hook);
result = CALL_ONE_PARAMETER_UPP( orig_menu_select, MenuSelectUPPInfo, pt);
LMSetMBarHook(old_hook);
DisposeRoutineDescriptor(mbar_hook);
}
DrawMenuBar();
return result;
}
void main(void)
{
Handle initCode = nil;
THz theZone;
initCode = Get1Resource('INIT', 0);
if (initCode == nil)
goto failure;
DetachResource(initCode);
if (ResError() != noErr)
goto failure;
theZone = GetZone();
SetZone(SystemZone());
HLockHi(initCode);
HNoPurge(initCode);
init_icon();
orig_draw_menubar = ApplyTrapPatch( _DrawMenuBar, NewRoutineDescriptor((ProcPtr)(PatchedDrawMenubar), DrawMenuBarUPPInfo, GetCurrentArchitecture()) );
orig_menu_select = ApplyTrapPatch( _MenuSelect, NewRoutineDescriptor((ProcPtr)(MenuSelectPatch), MenuSelectUPPInfo, GetCurrentArchitecture()) );
failure:;
}